From ae51ad74796ed32bc82b31d935dc3296344919ab Mon Sep 17 00:00:00 2001 From: Jeroen van der Heijden Date: Wed, 6 Mar 2019 16:35:03 +0100 Subject: [PATCH] Fixed querying many series by name, solves #118 --- grammar/grammar.py | 6 ++ include/siri/grammar/grammar.h | 2 +- include/siri/version.h | 2 +- itest/test_parentheses.py | 145 ++++++++++++++++++++++----------- itest/test_select.py | 7 ++ src/siri/db/query.c | 23 ++++++ src/siri/grammar/grammar.c | 13 ++- 7 files changed, 148 insertions(+), 50 deletions(-) diff --git a/grammar/grammar.py b/grammar/grammar.py index 47152d6c..fea49e33 100644 --- a/grammar/grammar.py +++ b/grammar/grammar.py @@ -423,6 +423,12 @@ class SiriGrammar(Grammar): uuid = Choice(r_uuid_str, string, most_greedy=False) group_match = Repeat(r_grave_str, 1, 1) series_match = Prio( + List(Choice( + series_all, + series_name, + group_match, + series_re, + most_greedy=False), series_setopr, 1), Choice( series_all, series_name, diff --git a/include/siri/grammar/grammar.h b/include/siri/grammar/grammar.h index b4d098b6..3f41f461 100644 --- a/include/siri/grammar/grammar.h +++ b/include/siri/grammar/grammar.h @@ -5,7 +5,7 @@ * should be used with the libcleri module. * * Source class: SiriGrammar - * Created at: 2019-01-03 10:42:54 + * Created at: 2019-03-06 11:59:02 */ #ifndef CLERI_EXPORT_SIRI_GRAMMAR_GRAMMAR_H_ #define CLERI_EXPORT_SIRI_GRAMMAR_GRAMMAR_H_ diff --git a/include/siri/version.h b/include/siri/version.h index 77091664..2d07f755 100644 --- a/include/siri/version.h +++ b/include/siri/version.h @@ -15,7 +15,7 @@ * Note that debian alpha packages should use versions like this: * 2.0.30-0alpha0 */ -#define SIRIDB_VERSION_PRE_RELEASE "-alpha-0" +#define SIRIDB_VERSION_PRE_RELEASE "-alpha-1" #ifndef NDEBUG #define SIRIDB_VERSION_BUILD_RELEASE "+debug" diff --git a/itest/test_parentheses.py b/itest/test_parentheses.py index c31be363..26a48fc9 100644 --- a/itest/test_parentheses.py +++ b/itest/test_parentheses.py @@ -88,29 +88,38 @@ class TestParenth(TestBase): {'success_msg': 'Successfully inserted {} point(s).'.format( LENPOINTS)}) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series all - ("series-001" | "series-002" | /windows.*/) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-003'], ['series-004'], ['linux-001'], ['linux-002'], ['linux-003'], - ['linux-004']]}) + ['linux-004'] + ]) + } + ) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series all - ( "series-001" | "series-002" | (/windows.*/ & /.*001/)) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-003'], ['series-004'], ['linux-001'], @@ -119,52 +128,72 @@ class TestParenth(TestBase): ['linux-004'], ['windows-002'], ['windows-003'], - ['windows-004']]}) - - self.assertEqual( - await self.client0.query(''' + ['windows-004'] + ]) + } + ) + result = await self.client0.query(''' list series all - ( "series-001" | "series-002" | (/windows.*/ - /.*001/)) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-003'], ['series-004'], ['linux-001'], ['linux-002'], ['linux-003'], ['linux-004'], - ['windows-001']]}) + ['windows-001'] + ]) + } + ) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series ( "series-001" | "series-002" | /windows.*/) - /.*003/ - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-001'], ['series-002'], ['windows-001'], ['windows-002'], - ['windows-004']]}) + ['windows-004'] + ]) + } + ) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series all - (/series.*/ ^ /.*001/) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-001'], ['linux-002'], ['linux-003'], ['linux-004'], ['windows-002'], ['windows-003'], - ['windows-004']]}) + ['windows-004'] + ]) + } + ) self.assertEqual( await self.client0.query(''' @@ -174,49 +203,73 @@ class TestParenth(TestBase): 'columns': ['name'], 'series': []}) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series /.*001/ & (/series.*/ | /linux.*/) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-001'], - ['linux-001']]}) + ['linux-001'] + ]) + } + ) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series /.*001/ & ((((/series.*/ | /linux.*/)))) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-001'], - ['linux-001']]}) + ['linux-001'] + ]) + } + ) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series (/.*001/ | /.*002/) & (/series.*/ | /linux.*/) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-001'], ['series-002'], ['linux-001'], - ['linux-002']]}) + ['linux-002'] + ]) + } + ) - self.assertEqual( - await self.client0.query(''' + result = await self.client0.query(''' list series ((/.*001/ | /.*002/) & (/series.*/ | /linux.*/)) - '''), + ''') + result['series'] = sorted(result['series']) + + self.assertEqual( + result, { 'columns': ['name'], - 'series': [ + 'series': sorted([ ['series-001'], ['series-002'], ['linux-001'], - ['linux-002']]}) + ['linux-002'] + ]) + } + ) with self.assertRaisesRegex( QueryError, diff --git a/itest/test_select.py b/itest/test_select.py index 70af9cb0..d688412d 100644 --- a/itest/test_select.py +++ b/itest/test_select.py @@ -217,6 +217,13 @@ class TestSelect(TestBase): [1447254000, 31530.520833333332], [1447257600, 4.666666666666667]]}) + self.assertEqual( + await self.client0.query('select * from {}'.format( + ','.join(['"aggr"'] * 600) + )), + {'aggr': DATA['aggr']} + ) + self.assertEqual( await self.client0.query('select difference(1h) from "aggr"'), {'aggr': [[1447250400, 1], [1447254000, -3], [1447257600, 5]]}) diff --git a/src/siri/db/query.c b/src/siri/db/query.c index 02e5cd2a..d4807b16 100644 --- a/src/siri/db/query.c +++ b/src/siri/db/query.c @@ -405,6 +405,26 @@ void siridb_query_timeit_from_unpacker( } } +static void QUERY_unique(cleri_olist_t * olist) +{ + while (olist != NULL && olist->next != NULL) + { + cleri_olist_t * test = olist; + while (test->next != NULL) + { + if (olist->cl_obj == test->next->cl_obj) + { + cleri_olist_t * tmp = test->next->next; + free(test->next); + test->next = tmp; + continue; + } + test = test->next; + } + olist = olist->next; + } +} + static void QUERY_send_invalid_error(uv_async_t * handle) { size_t len; @@ -419,6 +439,9 @@ static void QUERY_send_invalid_error(uv_async_t * handle) "Query error at position %zd. Expecting ", query->pr->pos); + /* required for libcleri versions prior to 0.10.1 */ + QUERY_unique(query->pr->expecting->required); + /* expand the error message with suggestions. we try to add nice names * for regular expressions etc. */ diff --git a/src/siri/grammar/grammar.c b/src/siri/grammar/grammar.c index 305d4c6d..6ed2519f 100644 --- a/src/siri/grammar/grammar.c +++ b/src/siri/grammar/grammar.c @@ -5,7 +5,7 @@ * should be used with the libcleri module. * * Source class: SiriGrammar - * Created at: 2019-01-03 10:42:54 + * Created at: 2019-03-06 11:59:02 */ #include "siri/grammar/grammar.h" @@ -781,7 +781,16 @@ cleri_grammar_t * compile_siri_grammar_grammar(void) cleri_t * group_match = cleri_dup(CLERI_GID_GROUP_MATCH, r_grave_str); cleri_t * series_match = cleri_prio( CLERI_GID_SERIES_MATCH, - 3, + 4, + cleri_list(CLERI_NONE, cleri_choice( + CLERI_NONE, + CLERI_FIRST_MATCH, + 4, + series_all, + series_name, + group_match, + series_re + ), series_setopr, 1, 0, 0), cleri_choice( CLERI_NONE, CLERI_FIRST_MATCH, -- 2.30.2